﻿using System;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif

namespace JH
{
    public static class SetBoxColliderSize
    {
        /// <summary>
        /// 根据模型的顶点信息，生成一个刚刚好的boxCollider
        /// </summary>
        /// <param name="boxCollider">需要计算的碰撞体</param>
        /// <param name="includeInactive">计算包围盒时，是否包含未激活的物体</param>
        /// <exception cref="ArgumentNullException">参数为空将会抛出空参数异常</exception>
        public static void SetSizeAndCenterFromGameObjectEm(this BoxCollider boxCollider, bool includeInactive = false)
        {
            if (boxCollider == null) throw new ArgumentNullException(nameof(boxCollider), "传入的BoxCollider为空");

            //模型包围盒的计算，需要将移动旋转归零，否则会出现计算的包围盒不准确的情况
            (Quaternion rotation, Vector3 position) = (boxCollider.transform.rotation, boxCollider.transform.position);
            boxCollider.transform.SetPositionAndRotation(Vector3.zero, Quaternion.identity);

            // 获取并设置模型缩放
           Dictionary<Transform,Vector3> scaleDic = new Dictionary<Transform, Vector3>();
           var current = boxCollider.transform;
           while (current != null)
           {
                scaleDic.Add(current,current.localScale);
                 current.localScale = Vector3.one;
                current = current.parent;
           }
            
            //获取模型的包围盒
            Bounds bounds = boxCollider.gameObject.GetBoundsEm(includeInactive);

            //设置boxCollider的大小和中心
            boxCollider.center = bounds.center;
            boxCollider.size = bounds.size;

            //恢复模型的位置和旋转
            boxCollider.transform.SetPositionAndRotation(position, rotation);
            
            //恢复模型的缩放
            foreach (var item in scaleDic)
            {
                item.Key.localScale = item.Value;
            }
        }

#if UNITY_EDITOR
        /// <summary>
        ///  在编辑器中设置BoxCollider的大小和中心
        /// </summary>
        [MenuItem("CONTEXT/BoxCollider/CalcBounds")]
        public static void CalcBoxCollider(MenuCommand menuCommand)
        {
            BoxCollider boxCollider = menuCommand.context as BoxCollider;
            boxCollider.SetSizeAndCenterFromGameObjectEm();
        }

        /// <summary>
        ///  在编辑器中设置BoxCollider的大小和中心，包括未激活的物体
        /// </summary>
        [MenuItem("CONTEXT/BoxCollider/CalcBoundsWithInactive")]
        public static void CalcBoundsWithInactive(MenuCommand menuCommand)
        {
            BoxCollider boxCollider = menuCommand.context as BoxCollider;
            boxCollider.SetSizeAndCenterFromGameObjectEm(true);
        }

#endif
    }
}